09-14-2021
首先我們要先知道我們需要在子組件更改的位置並且定義。
是在line10``<h1> Hey my name is {this.props.name}! </h1>
下拉選單選擇了顯示的項目value會返回給name顯示
// Child.js
import React from 'react';
export class Child extends React.Component {
render() {
return (
<div>
<h1>
Hey there, I'am {this.props.name}!
</h1>
<select id="great-names">
<option value="Frarthur">
Frarthur
</option>
<option value="Gromulus">
Gromulus
</option>
<option value="Thinkpiece">
Thinkpiece
</option>
</select>
</div>
);
}
}
在父組件中,我們需要先import<Child/>
component到頁面中。
並且使用setState()
定義一個狀態的事件。
// Parent.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Child } from './Child';
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {name:'Frarthur'};
}
changeName(newName){
this.setState({
name:newName
});
}
render() {
return <Child name={this.state.name} />
}
}
ReactDOM.render(
<Parent />,
document.getElementById('app')
);
以上是狀態的設置
可以將監聽事件傳遞下去了,接著是要傳遞事件處理的方式。bind
this
changeName()在constructor裡面,把函式傳遞下去給子組件,而要在傳遞的component上使用onChange
把要傳遞的方法寫上去
// Parent.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Child } from './Child';
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {name:'Frarthur'};
this.changeName = this.changeName.bind(this);
}
changeName(newName){
this.setState({
name:newName
});
}
render() {
return <Child name={this.state.name} onChange={ this.changeName } />
}
}
ReactDOM.render(
<Parent />,
document.getElementById('app')
);
我們使用props傳遞方法下來子層,理當會先在需要改變的<select>
上放上接props的方式onChange(this.props.onChange)
但我們少了傳遞props的橋樑,以及需要傳遞的參數,因為這不會傳遞一個名稱,而是會傳遞一個事件的物件,所以這個函數應該要接收一個event object作為參數,才可以調用這個函式。
handleChange(e) {
const name = e.target.value;
this.props.onChange(name);
}
stateless component 綁定方式
// Child.js
export class Child extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange(e) {
const name = e.target.value;
this.props.onChange(name);
}
render() {
return (
<div>
<h1 >
Hey my name is {this.props.name}!
</h1>
<select id="great-names" onChange={this.handleChange}>
<option value="Frarthur">
Frarthur
</option>
<Child / >
和<sibling />
兩個compoents首先,確認import了<sibling />
這個component在頁面上,以及在return時有把<sibling / >
放進來,最後確認與<Child />
,使用同一個外層包裝起來的<div></div>
<sibling/ >
的主要工作是顯示選擇的名稱,name={this.state.name}
要顯示的name
是存在Parents
中的state
,所以可以透過名稱傳遞給sibling
並且顯示。
同時<Child/>
的工作是提供更改所選名稱的方法,而不是==顯示==,所以我們把原本的onChange()
與顯示的name
都從Parents
移除
我們現在已經將<sibling/>
作為prop傳遞了。
所以我們要在prop
顯示要傳遞的name
。
在<sibling/>
中,宣告一個新的變數name
,讓變數等於prop傳遞的name
,將文句中要替換的名稱改為變數,name
// parent.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Child } from './Child';
import { Sibling } from './Sibling';
// 引入子組件
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = { name: 'Frarthur' };
// 預設要顯示的名稱
this.changeName = this.changeName.bind(this);
// 綁定要更改的方法
}
// 更改的方法
changeName(newName) {
this.setState({
name: newName
});
}
render() {
return (
<div>
// <Child
// name={this.state.name}
// onChange={this.changeName} />
// 將原本在一個component中要做的事情分給兄弟姐妹執行
<Child onChange={this.changeName} />
// 負責更改名稱的方式
<Sibling name={this.state.name} />
// 負責更改狀態要顯示的名字
</div>
);
}
}
ReactDOM.render(
<Parent />,
document.getElementById('app')
);
// Child.js
import React from 'react';
export class Child extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
// 綁定更改的方法
}
// 選擇到的value傳到方法中
handleChange(e) {
const name = e.target.value;
this.props.onChange(name);
}
render() {
return (
<div>
<select
id="great-names"
onChange={this.handleChange}>
<option value="Frarthur">Frarthur</option>
<option value="Gromulus">Gromulus</option>
<option value="Thinkpiece">Thinkpiece</option>
</select>
</div>
);
}
}
// sibling.js
import React from 'react';
export class Sibling extends React.Component {
render() {
const name = this.props.name
// 設定變數接傳遞的過來的`name`
return (
// <div>
// <h1>Hey, my name is Frarthur!</h1>
// <h2>Don't you think Frarthur is the prettiest name ever?</h2>
// <h2>Sure am glad that my parents picked Frarthur!</h2>
// </div>
// 原本的標題內容都只能出現一個名稱,用變數{name}呈現就會改變名字了!
<div>
<h1>Hey, my name is {name}!</h1>
<h2>Don't you think {name} is the prettiest name ever?</h2>
<h2>Sure am glad that my parents picked {name}!</h2>
</div>
);
}
}
在parent中定義了一個狀態的function:this.statechangeName(newName) { this.setState({ name: newName }); }
有狀態的component將function往下傳遞給無狀態的component <Child onChange={this.changeName} />
這個無狀態的class function定義了傳遞函數,這個傳遞函數可以做為參數使用<Child /> handleChange(e) { const name = e.target.value; this.props.onChange(name); }
這個無狀態組件的componet使用了一個新的方程式當作事件程序<Child /> onChange={this.handleChange}>
當事件發生了改變,parent 的 state狀態更新時(選擇了下拉選單)
這個有狀態的component就會把狀態往下傳遞給無狀態component,這與改變state的方式不同<Sibling name={this.state.name} />
無狀態componet class(sibling) 接收到了state 於是就顯示它<sibling/> const name = this.props.name;
總的來說,有狀態的component只負責render,<Child/ >負責state,負責顯示切換的state